package com.zuorenke.redis;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.HashSet;
import java.util.Set;

public class JedisClusterFactory extends BasePooledObjectFactory<JedisCluster> implements InitializingBean {
	
	private static final Logger logger = LoggerFactory.getLogger(JedisClusterFactory.class);
	
	private Integer timeout;
	
	private Integer maxRedirections;
	
	private GenericObjectPoolConfig rcPoolConf;
	
	private Set<HostAndPort> nodeSet;
	
	private String hostAndPortConf;
	
	public void setTimeout(Integer timeout) {
		this.timeout = timeout;
	}
	
	public void setMaxRedirections(Integer maxRedirections) {
		this.maxRedirections = maxRedirections;
	}
	
	public void setRcPoolConf(GenericObjectPoolConfig rcPoolConf) {
		this.rcPoolConf = rcPoolConf;
	}
	
	public void setNodeSet(Set<HostAndPort> nodeSet) {
		this.nodeSet = nodeSet;
	}
	
	public void setHostAndPortConf(String hostAndPortConf) {
		this.hostAndPortConf = hostAndPortConf;
	}
	
	@Override
	public void afterPropertiesSet() {
		logger.info("init redis nodes");
		nodeSet = new HashSet<>();
		String[] cNodes = hostAndPortConf.split(",");
		for (String node : cNodes) {
			String[] hp = node.split(":");
			nodeSet.add(new HostAndPort(hp[0], Integer.parseInt(hp[1])));
		}
	}
	
	@Override
	public JedisCluster create() throws Exception {
		return new JedisCluster(nodeSet, timeout, maxRedirections, rcPoolConf);
	}
	
	@Override
	public PooledObject<JedisCluster> wrap(JedisCluster jc) {
		return new DefaultPooledObject(jc);
	}
	
	@Override
	public boolean validateObject(PooledObject<JedisCluster> p) {
		final JedisCluster jc = p.getObject();
		try {
			jc.exists("1");
			return true;
		}catch (final Exception e){
			return false;
		}
	}
	
}
